package com.example.myapplication.function.keyboard

import android.content.Context
import android.media.AudioAttributes
import android.media.SoundPool
import android.util.Log
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
import java.io.File
import java.io.IOException

class PianoAudioManager(context: Context) {
    private val soundPool: SoundPool
    private val soundMap = mutableMapOf<String, Int>()
    private val context = context.applicationContext
    private var loadCompleteListener: SoundPool.OnLoadCompleteListener? = null

    companion object {
        private const val MAX_STREAMS = 20
        private const val SAMPLE_RATE = 44100
    }

    init {
        val attributes = AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build()

        soundPool = SoundPool.Builder()
            .setAudioAttributes(attributes)
            .setMaxStreams(MAX_STREAMS)
            .build()

        // 设置加载完成监听器
        setupLoadCompleteListener()
    }

    private fun setupLoadCompleteListener() {
        loadCompleteListener = SoundPool.OnLoadCompleteListener { soundPool, sampleId, status ->
            Log.d("AudioManager", "Sound loaded - ID: $sampleId, Status: $status")
            if (status == 0) {
                // 加载成功
            } else {
                Log.e("AudioManager", "Failed to load sound: $sampleId")
            }
        }
        soundPool.setOnLoadCompleteListener(loadCompleteListener)
    }

    /**
     * 加载钢琴音源库 - 修复版本
     */
    fun loadPianoSoundLibrary(soundLibrary: Map<String, PianoSoundGenerator.PianoNote>) {
        soundMap.clear()

        // 只加载常用音符避免内存问题
        val commonNotes = listOf(
            "C3", "D3", "E3", "F3", "G3", "A3", "B3",
            "C4", "D4", "E4", "F4", "G4", "A4", "B4",
            "C5", "D5", "E5", "F5", "G5", "A5", "B5"
        )

        Thread {
            commonNotes.forEach { noteName ->
                val pianoNote = soundLibrary[noteName]
                if (pianoNote != null) {
                    try {
                        // 使用更可靠的WAV生成方法
                        val wavData = createProperWavFile(pianoNote.sampleData, SAMPLE_RATE)
                        loadSoundToSoundPool(noteName, wavData)
                        Thread.sleep(50) // 避免加载过快
                    } catch (e: Exception) {
                        Log.e("AudioManager", "Failed to load $noteName: ${e.message}")
                    }
                }
            }

            // 检查加载结果
            Log.d("AudioManager", "Sound loading completed. Loaded ${soundMap.size} sounds")
        }.start()
    }

    /**
     * 创建正确的WAV文件
     */
    private fun createProperWavFile(audioData: FloatArray, sampleRate: Int): ByteArray {
        val baos = ByteArrayOutputStream()
        val dos = DataOutputStream(baos)

        val numSamples = audioData.size
        val byteRate = sampleRate * 2
        val dataSize = numSamples * 2
        val totalSize = 36 + dataSize

        try {
            // RIFF header
            dos.writeBytes("RIFF")
            writeLittleEndianInt(dos, totalSize)
            dos.writeBytes("WAVE")

            // fmt chunk
            dos.writeBytes("fmt ")
            writeLittleEndianInt(dos, 16) // PCM chunk size
            writeLittleEndianShort(dos, 1) // PCM format
            writeLittleEndianShort(dos, 1) // mono
            writeLittleEndianInt(dos, sampleRate)
            writeLittleEndianInt(dos, byteRate)
            writeLittleEndianShort(dos, 2) // block align
            writeLittleEndianShort(dos, 16) // bits per sample

            // data chunk
            dos.writeBytes("data")
            writeLittleEndianInt(dos, dataSize)

            // audio data
            for (i in 0 until numSamples) {
                val sample = (audioData[i] * 32767.0).toInt().coerceIn(-32768, 32767)
                writeLittleEndianShort(dos, sample)
            }

        } catch (e: Exception) {
            Log.e("AudioManager", "Error creating WAV file", e)
        } finally {
            try {
                dos.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }

        return baos.toByteArray()
    }

    private fun writeLittleEndianInt(dos: DataOutputStream, value: Int) {
        dos.writeByte(value and 0xff)
        dos.writeByte(value shr 8 and 0xff)
        dos.writeByte(value shr 16 and 0xff)
        dos.writeByte(value shr 24 and 0xff)
    }

    private fun writeLittleEndianShort(dos: DataOutputStream, value: Int) {
        dos.writeByte(value and 0xff)
        dos.writeByte(value shr 8 and 0xff)
    }

    /**
     * 加载声音到SoundPool - 修复版本
     */
    private fun loadSoundToSoundPool(noteName: String, wavData: ByteArray) {
        try {
            // 创建临时文件
            val tempFile = File.createTempFile("sound_${System.currentTimeMillis()}", ".wav", context.cacheDir)
            tempFile.outputStream().use { it.write(wavData) }

            Log.d("AudioManager", "Loading sound for $noteName from ${tempFile.absolutePath}")

            // 使用load方法加载文件
            val soundId = soundPool.load(tempFile.absolutePath, 1)

            if (soundId != 0) {
                soundMap[noteName] = soundId
                Log.d("AudioManager", "Successfully loaded $noteName with ID: $soundId")
            } else {
                Log.e("AudioManager", "Failed to load $noteName - soundId is 0")
            }

            // 不立即删除文件，等播放完成后再清理
            tempFile.deleteOnExit()

        } catch (e: Exception) {
            Log.e("AudioManager", "Error loading sound for $noteName", e)
        }
    }

    /**
     * 播放音符 - 修复版本
     */
    fun playNote(noteName: String, volume: Float = 1.0f): Int {
        val soundId = soundMap[noteName]

        if (soundId == null) {
            Log.e("AudioManager", "Sound not found for note: $noteName")
            Log.d("AudioManager", "Available sounds: ${soundMap.keys}")
            return 0
        }

        if (soundId == 0) {
            Log.e("AudioManager", "Invalid sound ID (0) for note: $noteName")
            return 0
        }

        Log.d("AudioManager", "Playing note: $noteName, soundId: $soundId, volume: $volume")

        return try {
            val streamId = soundPool.play(soundId, volume, volume, 1, 0, 1.0f)
            if (streamId == 0) {
                Log.e("AudioManager", "Play failed for soundId: $soundId")
            } else {
                Log.d("AudioManager", "Play successful, streamId: $streamId")
            }
            streamId
        } catch (e: Exception) {
            Log.e("AudioManager", "Exception during play: ${e.message}")
            0
        }
    }

    /**
     * 检查声音是否加载完成
     */
    fun isSoundLoaded(noteName: String): Boolean {
        return soundMap[noteName] != null && soundMap[noteName] != 0
    }

    /**
     * 获取已加载的声音数量
     */
    fun getLoadedSoundCount(): Int {
        return soundMap.size
    }

    fun release() {
        soundPool.release()
    }
}